package com.example.myapplicationndk.mvp;


import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import com.example.myapplicationndk.R;

import java.lang.ref.WeakReference;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import me.jingbin.bymvvm.utils.ToastUtil;


/**
 * 网络请求基本订阅
 * Author     Vin
 * Mail       vinint@126.com
 * Createtime 2018/11/9 上午9:26
 * Modifytime 2018/11/9 上午9:26
 */
public abstract class BaseNetObserver<T> implements Observer<BaseResponseDto<T>> {

    private static final String TAG = "BaseNetObserver";
    //整个应用上下文
    private WeakReference<Context> mAppContext;
    //当前上下文
    private WeakReference<Context> mCurrentContext;
    //Rx生命周期控制
    private WeakReference<RxLifecycleManage> mRxLifecycleManage;

    private Boolean isShowNetProgressDialog = false;

    private Dialog mNetProgressDialog;


    protected BaseNetObserver(Context context) {
        this.mCurrentContext = new WeakReference<>(context);
        this.mAppContext = new WeakReference<>(context.getApplicationContext());

    }

    protected BaseNetObserver(Context context, Boolean isShowNetProgressDialog) {
        this.mCurrentContext = new WeakReference<>(context);
        this.mAppContext = new WeakReference<>(context.getApplicationContext());
        this.isShowNetProgressDialog = isShowNetProgressDialog;
//        if (isShowNetProgressDialog) {
//            mNetProgressDialog = new Dialog(mCurrentContext, R.style.NetProgressDialog);
//            View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_net_progress, null);
//            mNetProgressDialog.setContentView(dialogView);
//            mNetProgressDialog.show();
//            mNetProgressDialog.setCancelable(true);
//            mNetProgressDialog.setCanceledOnTouchOutside(true);
//        }
    }

    protected BaseNetObserver() {
//        if (isShowNetProgressDialog) {
//            mNetProgressDialog = new Dialog(mCurrentContext, R.style.NetProgressDialog);
//            View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_net_progress, null);
//            mNetProgressDialog.setContentView(dialogView);
//            mNetProgressDialog.show();
//            mNetProgressDialog.setCancelable(true);
//            mNetProgressDialog.setCanceledOnTouchOutside(true);
//        }
    }

    protected BaseNetObserver(Context context, RxLifecycleManage rxLifecycleManage, Boolean isShowNetProgressDialog) {
        this.mCurrentContext = new WeakReference<>(context);
        this.mAppContext = new WeakReference<>(context.getApplicationContext());
        this.mRxLifecycleManage = new WeakReference<>(rxLifecycleManage);
        this.isShowNetProgressDialog = isShowNetProgressDialog;
        if (isShowNetProgressDialog && mCurrentContext.get() != null && !((Activity) mCurrentContext.get()).isFinishing()) {
            mNetProgressDialog = new Dialog(mCurrentContext.get());
            View dialogView = LayoutInflater.from(mCurrentContext.get()).inflate(R.layout.dialog_net_progress, null);
            Window window = mNetProgressDialog.getWindow();
            WindowManager m = ((Activity) mCurrentContext.get()).getWindowManager();
            Display d = m.getDefaultDisplay(); // 获取屏幕宽、高用
            WindowManager.LayoutParams p = window.getAttributes(); // 获取对话框当前的参数值
            p.height = (int) (d.getHeight() * 0.6); // 改变的是dialog框在屏幕中的位置而不是大小
            p.width = (int) (d.getWidth() * 0.65); // 宽度设置为屏幕的0.65
            window.setAttributes(p);
            mNetProgressDialog.setContentView(dialogView);
            mNetProgressDialog.show();
            mNetProgressDialog.setCancelable(true);
            mNetProgressDialog.setCanceledOnTouchOutside(true);
        }
    }

    protected BaseNetObserver(Context context, RxLifecycleManage rxLifecycleManage, Boolean isShowNetProgressDialog, boolean isControll) {
        this.mCurrentContext = new WeakReference<>(context);
        this.mAppContext = new WeakReference<>(context.getApplicationContext());
        this.mRxLifecycleManage = new WeakReference<>(rxLifecycleManage);
        this.isShowNetProgressDialog = isShowNetProgressDialog;
        if (isShowNetProgressDialog && mCurrentContext.get() != null && !((Activity) mCurrentContext.get()).isFinishing()) {
            mNetProgressDialog = new Dialog(mCurrentContext.get());
            View dialogView = LayoutInflater.from(mCurrentContext.get()).inflate(R.layout.dialog_net_progress, null);
            Window window = mNetProgressDialog.getWindow();
            WindowManager m = ((Activity) mCurrentContext.get()).getWindowManager();
            Display d = m.getDefaultDisplay(); // 获取屏幕宽、高用
            WindowManager.LayoutParams p = window.getAttributes(); // 获取对话框当前的参数值
            p.height = (int) (d.getHeight() * 0.6); // 改变的是dialog框在屏幕中的位置而不是大小
            p.width = (int) (d.getWidth() * 0.65); // 宽度设置为屏幕的0.65
            window.setAttributes(p);
            mNetProgressDialog.setContentView(dialogView);
            mNetProgressDialog.show();
            if (isControll) {
                mNetProgressDialog.setCancelable(true);
                mNetProgressDialog.setCanceledOnTouchOutside(true);
            } else {
                mNetProgressDialog.setCancelable(false);
                mNetProgressDialog.setCanceledOnTouchOutside(false);
            }

        }
    }

    @Override
    public void onSubscribe(Disposable d) {
        if (mRxLifecycleManage != null && mRxLifecycleManage.get() != null) {
            mRxLifecycleManage.get().add(d);
        }
    }

    @Override
    public void onNext(BaseResponseDto<T> value) {
        //影藏网络请求框
        if (mNetProgressDialog != null) {
            mNetProgressDialog.dismiss();
            mNetProgressDialog = null;
        }
        Log.d(TAG, value == null ? "nullll" : value.toString());
        if (value.getStatus() == null) {
            onHandleSuccess(value.getData());
        } else if (value.getStatus() == 0) {
            onHandleSuccess(value.getData());
        } else if (value.getStatus() == 401) {
            //登录失效
            sessionaFilure(value.getStatus(), "登录信息失效，请重新登录!");
        } else {
            if (mCurrentContext.get() != null) {
                onHandleError(value.getStatus(), value.getMessage());
            }
        }
    }

    @Override
    public void onError(Throwable e) {
        if (mNetProgressDialog != null) {
            mNetProgressDialog.dismiss();
            mNetProgressDialog = null;
        }
        if (mCurrentContext.get() != null) {
            if (e instanceof SocketTimeoutException) {
                onHandleError(200, "网络或者服务器异常！");
            } else if (e instanceof ConnectException) {
                onHandleError(200, "网络或者服务器异常！");
            } else if (e.getMessage().contains("403")) {
                sessionaFilure(403, "登录失效，请重新登录");
            } else if (e.getMessage().contains("401")) {//需要重新登录
                onHandleError(401, "需要重新登录");
            } else {
                onHandleError(200, e.getMessage());
            }
        }

        Log.e(TAG, "error:" + e.toString());
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete");
    }

    protected abstract void onHandleSuccess(T t);

    protected void onHandleError(int errorNo, String strMsg) {
        if (errorNo == 401 || errorNo == 500 || strMsg.contains("HTTP 500 Internal Server Error")) {
            Log.d(TAG, "errorNo::" + errorNo + "////errorMsg:" + errorNo);
        } else if (mCurrentContext.get() != null && errorNo != 401) {
//            Toasty.error(mCurrentContext.get(), strMsg, Toast.LENGTH_SHORT, true).show();
//            Toast.makeText(mCurrentContext.get(), strMsg, Toast.LENGTH_SHORT).show();
            ToastUtil.showToast(strMsg);
        }
    }

    private void sessionaFilure(int errorNo, String strMsg) {
        if ((errorNo == -50000) || (errorNo == 401)) {


        }
    }
}

